#include "errormanager.hpp"
#include "game.hpp"
#include <iostream>

using namespace Shiny;

ErrorManager* ErrorManager::_errorManager = 0;

ErrorManager* ErrorManager::Get(void)
{
  if (!_errorManager)
    _errorManager = new BackupErrorManager;
  return (_errorManager);
}

void ErrorManager::AddError(const std::string& message, ErrorType type)
{
  Error error(message, type);

  _errors.push_back(error);
  std::cerr << "ErrorManager: " << message << std::endl;
}

void ErrorManager::DisplayError(std::list<Error>::iterator error)
{
  sf::RenderWindow&  target = *(_game->_window);
  sf::RectangleShape background;
  sf::Color          backgroundColor;
  sf::Text           text(error->message);
  sf::Text           leftErrorsText;
  unsigned int       sizeX;
  sf::Vector2f       position;
  sf::Event          event;

  switch (error->type)
  {
    case StopGame:
      backgroundColor = sf::Color(255, 0, 0, 125);
      break ;
    case Warning:
      backgroundColor = sf::Color(0, 255, 0, 125);
      break ;
    default:
      backgroundColor = sf::Color(0, 0, 0, 125);
      break ;
  }
  

  background.SetSize(sf::Vector2f(target.GetWidth(), target.GetHeight()));
  background.SetFillColor(backgroundColor);
  background.SetPosition(0.f, 0.f);

  sizeX      = target.GetWidth() / (error->message.length() + 2);
  position.x = sizeX;
  position.y = target.GetHeight() / 2 - (sizeX / 2);
  text.SetPosition(position);
  text.SetColor(sf::Color(255, 255, 255));

  if (_errors.size() > 1)
  {
    std::stringstream stream;

    stream << (_errors.size() - 1) << " other errors occured";
    leftErrorsText.SetString(stream.str());
  }

  target.Draw(background);
  target.Draw(leftErrorsText);
  target.Draw(text);
  target.Display();
  do
  {
    if (!(target.WaitEvent(event)))
      break ;
  } while ((event.Type != sf::Event::KeyReleased) && (event.Type != sf::Event::MouseButtonReleased));
}

bool ErrorManager::Run(void)
{
  bool hasToStop = false;
  
  if (_errors.size() > 0)
  {
    std::list<Error>::iterator it  = _errors.begin();
    std::list<Error>::iterator end = _errors.end();

    while (it != end)
    {
      DisplayError(it);
      if (it->type & StopGame) hasToStop = true;
      it = _errors.erase(it);
    }
  }
  return (!hasToStop);
}